#include <QDebug>
#include <QPainter>
#include <QApplication>
#include "Drive.h"
#include "File.h"
#include "FileTableModel.h"
#include "CommonDef.h"

const int CONST_iColumnNum = 4;
const int CONST_iPerBatchNum = 100;
const int CONST_iColumnWidth = 150;

CustomGridItemDelegate::CustomGridItemDelegate(QObject *p) : QStyledItemDelegate(p)
{
	m_dirImage = QPixmap(qApp->applicationDirPath() + "/Image/dir.png");
	m_fileImage = QPixmap(qApp->applicationDirPath() + "/Image/file.png");
	m_driveImage = QPixmap(qApp->applicationDirPath() + "/Image/ddisk.png");
}

void CustomGridItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
	QRectF rect = option.rect;
	if (painter == nullptr || !index.isValid())
	{
		return QStyledItemDelegate::paint(painter, option, index);
	}

	if (index.data().canConvert<TreeItem*>())
	{
		TreeItem* pItem = qvariant_cast<TreeItem*>(index.data());
		if (pItem == nullptr)
		{
			return QStyledItemDelegate::paint(painter, option, index);
		}

		TreeItemData* pData = pItem->data().value<TreeItemData*>();
		if (nullptr == pData)
		{
			return QStyledItemDelegate::paint(painter, option, index);
		}

		painter->setRenderHints(QPainter::Antialiasing);

		if (option.state & QStyle::State_Selected)
		{
			painter->fillRect(option.rect, QBrush(QColor(204, 232, 255)));
		}

		if (option.state & QStyle::State_MouseOver)
		{
			painter->fillRect(option.rect, QBrush(QColor(229, 243, 255)));
		}

		QString qstrTextName = pData->m_qstrName;
		std::wstring strPath;
		if (pItem->m_iType == TreeItemType_Drive)
		{
			Drive* pDrive = pData->m_data.value<Drive*>();
			if (pDrive == nullptr)
			{
				return QStyledItemDelegate::paint(painter, option, index);
			}

			strPath = pDrive->m_wsName + L":";
		}
		else if (pItem->m_iType == TreeItemType_Dir || pItem->m_iType == TreeItemType_File)
		{
			File* pFile = pData->m_data.value<File*>();
			if (pFile == nullptr)
			{
				return QStyledItemDelegate::paint(painter, option, index);
			}

			strPath = pFile->m_wsPath;
		}
		else
		{
			return QStyledItemDelegate::paint(painter, option, index);
		}


		QPixmap pixmap;
		CommonFunc::GetBigICon(strPath, pixmap);

		if (pItem->m_iType == FileNodeType_Dir)
		{
			painter->drawPixmap(QRect(rect.x()+20, rect.y()+5, 80, 80), m_dirImage);
		}
		else if (pItem->m_iType == FileNodeType_File)
		{
			painter->drawPixmap(QRect(rect.x()+20, rect.y()+5, 80, 80), pixmap);
		}
		else
		{
			painter->drawPixmap(QRect(rect.x()+20, rect.y()+5, 80, 80), pixmap);
		}

		
		QFont pFont("Microsoft Yahei");
		pFont.setPixelSize(12);
		painter->setFont(pFont);
		pFont.setStretch(QFont::Unstretched);
		QFontMetrics font(pFont);
		qstrTextName = font.elidedText(qstrTextName, Qt::ElideRight, 119);
		painter->drawText(QRect(rect.x(), rect.y()+80, 120, rect.height()-80), Qt::AlignCenter, qstrTextName);
	}
	else
	{
		return QStyledItemDelegate::paint(painter, option, index);
	}
}

QSize CustomGridItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	return QSize(120, 110);
}

FileTableModel::FileTableModel(QObject *parent)
	: QAbstractListModel(parent)
{
}

FileTableModel::~FileTableModel()
{

}

int FileTableModel::rowCount(const QModelIndex &_index) const
{
	return _index.isValid() ? 0 : m_iCurCount;
}

QVariant FileTableModel::data(const QModelIndex &_index, int _iRole) const
{
	if (!_index.isValid() || _index.row() > m_iCurCount)
	{
		return QVariant();
	}

	if (m_iCurCount < 0 || m_iCurCount > m_qvecData.size())
	{
		return QVariant();
	}

	TreeItem* data = m_qvecData.at(_index.row());
	if (nullptr == data)
	{
		return QVariant();
	}

	return QVariant::fromValue(data);
}

void FileTableModel::SetData(const QList<TreeItem*> &_vecFiles)
{
	beginResetModel();
	m_qvecData = _vecFiles;
	m_iCurCount = 0;
	endResetModel();
}

void FileTableModel::Clear()
{
	beginResetModel();
	m_qvecData.clear();
	m_iCurCount = 0;
	endResetModel();
}

bool FileTableModel::canFetchMore(const QModelIndex &parent) const
{
	if (parent.isValid())
	{
		return false;
	}
	return (m_iCurCount < m_qvecData.size());
}

void FileTableModel::fetchMore(const QModelIndex &parent)
{
	if (parent.isValid())
	{
		return;
	}

	int remainder = m_qvecData.size() - m_iCurCount;
	int itemsToFetch = qMin(CONST_iPerBatchNum, remainder);
	if (itemsToFetch <= 0)
	{
		return;
	}

	beginInsertRows(QModelIndex(), m_iCurCount, m_iCurCount + itemsToFetch - 1);
	m_iCurCount += itemsToFetch;
	endInsertRows();
	emit numberPopulated(itemsToFetch);
}


int FileTableModel::GetData(const QModelIndex &_index, TreeItem* &_data)
{
	int iRet = RET_DEFAULT_CORRECT;
	if (!_index.isValid()) return RET_DEFAULT_ERROR;
	int iRow = _index.row();
	if (iRow < 0 || iRow >= m_iCurCount)
	{
		return RET_DEFAULT_ERROR;
	}

	_data = m_qvecData.at(iRow);
	return iRet;
}